﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlanB.ShareDove.ConferenceOrganization.BusinessLayer.DataLayerInterface;
using PlanB.Core.Configuration;
using System.Collections;
using PlanB.ShareDove.ConferenceOrganization.BusinessLayer.DataLayerInterface.Entities;
using System.IO;

namespace PlanB.ShareDove.ConferenceOrganization.BusinessLayer
{
    /// <summary>
    /// Business Layer for conference organization portal
    /// </summary>
    public partial class ConferenceOrganizationBusinessProcesses
    {

        #region Private members
        /// <summary>
        /// Data Layer implementation 
        /// </summary>
        private IConferenceOrganizationDataLayerInterface m_DataLayer;
        #endregion

        #region Public properties
        #endregion

        #region Constructors and configuration

        /// <summary>
        /// Creates an instance of the Business Layer. 
        /// </summary>
        /// <param name="configuration">Standard configuration class which holds the necessary information about data layer implementations, logging implementations, etc.</param>
        public ConferenceOrganizationBusinessProcesses(ConfigurationInformation configuration)
        {
            setDataLayerInstance(configuration.DataLayerImplementationAssembly, configuration.DataLayerImplementationClassName);
        }

        /// <summary>
        /// Sets an instance of the data layer
        /// </summary>
        /// <param name="dataLayerImplementation">Assembly that holds the data layer implementation</param>
        /// <param name="className">Name of the class which implements the data layer</param>
        private void setDataLayerInstance(string dataLayerImplementation, string className)
        {
            try
            {
                //
                //extract the assembly and class names from the full qualified assembly name
                string[] parts = dataLayerImplementation.Split(',');
                string assemblyName = parts[0].Trim();

                //
                // create an instance of the class from the assembly
                System.Reflection.Assembly assembly = null;

                //
                //first try to load the assembly from the BIN directory
                string localDll = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyName + ".dll");
                string binDll = System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"), assemblyName + ".dll");

                if (System.IO.File.Exists(localDll))
                {
                    //first check if the assembly exists in the executing directory
                    assembly = System.Reflection.Assembly.LoadFrom(localDll);
                }
                else if (System.IO.File.Exists(binDll))
                {
                    //if assembly is not in the executing directory, try to look in the bin folder under in - necessary for services
                    assembly = System.Reflection.Assembly.LoadFrom(binDll);
                }

                //
                //if that didn't work, try to load it from GAC
                if (assembly == null)
                {
                    try
                    {
                        assembly = System.Reflection.Assembly.Load(dataLayerImplementation);
                    }
                    catch (Exception ex)
                    {
                        throw new ApplicationException("Could not load business layer assembly.", ex);
                    }
                }

                //
                //instantiate class if the assembly has been properly loaded
                if (assembly != null)
                {
                    object instance = assembly.CreateInstance(className);

                    //
                    // check if this class implements ILandingPageProvider interface
                    if (instance is IConferenceOrganizationDataLayerInterface)
                    {
                        m_DataLayer = (IConferenceOrganizationDataLayerInterface)instance;
                    }
                    else
                    {
                        throw new ApplicationException("Class instance does not implement the business layer interface.");
                    }
                }
                else
                {
                    throw new ApplicationException("Could not load business layer assembly.");
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Unknown error by instantiating the Data Layer class", ex);
            }
        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Gets all sessions at the conference
        /// </summary>
        /// <param name="context">Current application context</param>
        /// <returns>Sessions for requested day</returns>
        public IEnumerable<ConferenceSession> GetAllSessions(object context)
        {
            IEnumerable<ConferenceSession> sessions = m_DataLayer.GetSessionData(context, null, null);
            return sessions;
        }

        /// <summary>
        /// Gets all sessions for a specified day
        /// </summary>
        /// <param name="context">Current application context</param>
        /// <param name="day">Day for which we want to get the sessions</param>
        /// <returns>Sessions for requested day</returns>
        public IEnumerable<ConferenceSession> GetSessionsForDay(object context, DateTime day)
        {
            IEnumerable<ConferenceSession> sessions = m_DataLayer.GetSessionData(context, day, null);
            return sessions;
        }


        #endregion

        #region Private Methods
        #endregion




    }

}
